package com.foreveross.bsl.mam.app.application.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.foreveross.bsl.common.utils.context.ContextThead;
import com.foreveross.bsl.common.utils.enums.AuthType;
import com.foreveross.bsl.file.storage.FileStorage;
import com.foreveross.bsl.file.storage.FileStorageFactory;
import com.foreveross.bsl.mam.app.application.AppMainApplication;
import com.foreveross.bsl.mam.app.application.AppVersionApplication;
import com.foreveross.bsl.mam.app.application.AppVersionWidgetVersionApplication;
import com.foreveross.bsl.mam.app.application.ClientWsApplication;
import com.foreveross.bsl.mam.app.application.vo.AppMainVo;
import com.foreveross.bsl.mam.app.application.vo.AppVersionVo;
import com.foreveross.bsl.mam.app.application.vo.AppVersionWidgetVersionVo;
import com.foreveross.bsl.mam.model.application.AttachmentApplication;
import com.foreveross.bsl.mam.model.application.WidgetApplication;
import com.foreveross.bsl.mam.model.application.WidgetSnapshotApplication;
import com.foreveross.bsl.mam.model.application.WidgetVersionApplication;
import com.foreveross.bsl.mam.model.application.vo.AttachmentVO;
import com.foreveross.bsl.mam.model.application.vo.WidgetSnapshotVO;
import com.foreveross.bsl.mam.model.application.vo.WidgetVO;
import com.foreveross.bsl.mam.model.application.vo.WidgetVersionVO;
import com.foreveross.bsl.mam.rbac.application.OperationApplication;
import com.foreveross.bsl.mam.rbac.application.PrivilegeApplication;
import com.foreveross.bsl.mam.rbac.application.vo.OperationVO;
import com.foreveross.bsl.mam.rbac.application.vo.PrivilegeVO;
import com.foreveross.bsl.mam.rbac.application.vo.RoleVO;
import com.foreveross.bsl.redis.cache.RedisCacheOperator;
import com.foreveross.bsl.system.application.AccountApplication;
import com.foreveross.bsl.system.application.ApplicationRegisterApplication;
import com.foreveross.bsl.system.application.vo.AccountVO;
import com.foreveross.bsl.system.application.vo.ApplicationRegisterVO;
import com.foreveross.bsl.system.application.extend.AuthSettingApplication;
import com.foreveross.bsl.system.application.extend.vo.AuthSettingVO;
import com.foreveross.bsl.mam.rbac.application.RoleApplication;
import com.foreveross.bsl.common.utils.mapper.JsonMapper;
import com.taobao.common.tfs.packet.FileInfo;

@Named("clientWsApplication")
public class ClientWsApplicationImpl implements ClientWsApplication {
	private Logger log = Logger.getLogger(this.getClass());

  @Inject
  private AuthSettingApplication authSettingApplication; // add by hyw 20140516 3rd配置 system-ws-client.xml文件修改

  @Inject
	private RoleApplication roleApplication;

	@Inject
	private AppMainApplication appMainApplication;

	@Inject
	private AppVersionApplication appVersionApplication;

	@Inject
	private AppVersionWidgetVersionApplication appVersionWidgetVersionApplication;

	@Inject
	private WidgetVersionApplication widgetVersionApplication;

	@Inject
	private WidgetApplication widgetApplication;

	@Inject
	private PrivilegeApplication privilegeApplication;

	@Inject
	private ApplicationRegisterApplication appRegServiceClient;

	@Inject
	private AttachmentApplication attachmentApplication;

	@Inject
	private WidgetSnapshotApplication widgetSnapshotApplication;

	// @Inject
	// private MonitorApplication monitorApplication;

	@Inject
	private AccountApplication accountApplication;

	@Inject
	private RedisCacheOperator operator;

	@Context
	private MessageContext context;
	
	@Inject OperationApplication operationApplication;

	@Override
	public Map<String, Object> getApps(String platform, String identifier,
			String version, String username) {
		return this.getAppsWidgets(platform, identifier, version, username,
				null);
	}

	@Override
	public Response validate(String platform, String identifier,
			String version, String secret, String appKey) {
		Map<String, String> params = new HashMap<String, String>();
		params.put("platform", platform);
		params.put("identifier", identifier);
		params.put("version", version);
		params.put("secert", secret);
		params.put("appKey", appKey);
		log.info("[validate]" + params.toString());
		ResponseBuilder responseBuilder = Response.ok();// 默认返回状态码200
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
			if (ar == null) {
				responseBuilder.status(400);// 即appKey密钥不正确
				log.info("[validate] 即appKey密钥不正确 " + appKey);
				return responseBuilder.build();
			}

			ContextThead.setThreadVar(ar.getUsername());// 路由租户数据库
			AppMainVo appVo = appMainApplication
					.getEntitybyIdentify(identifier); // 获取应用信息
			if (appVo == null) {
				responseBuilder.status(400);// 错误请求,应用标识不存在
				log.info("[validate] 应用标识不存在 " + identifier);
				return responseBuilder.build();
			}

			if (StringUtils.isNotEmpty(appVo.getSecret())
					&& appVo.getSecret().equals(secret)) {
				String token = UUID.randomUUID().toString();
				Calendar calendar = Calendar.getInstance();
				calendar.set(Calendar.DAY_OF_MONTH,
						calendar.get(Calendar.DAY_OF_MONTH) + 7);
				SimpleDateFormat sf = new SimpleDateFormat(
						"yyyy-MM-dd HH:mm:ss");
				String expired = sf.format(calendar.getTime());
				Map<String, String> redisMap = new HashMap<String, String>();
				redisMap.put("appKey", appKey);
				redisMap.put("identifier", identifier);
				redisMap.put("platform", platform);
				redisMap.put("version", version);
				redisMap.put("token", token);
				redisMap.put("expired", expired);
				operator.set(redisMap, token);
				result.put("token", token);
				result.put("expired", expired);
				responseBuilder.status(200);
				responseBuilder.entity(result);
			} else {
				responseBuilder.status(400);// 没有权限（即secret密钥不正确）
				log.info("[validate] 即secret密钥不正确 " + secret);
			}
		} catch (Exception e) {
			log.error("[validate]", e);
			responseBuilder.status(500);// 服务器异常
		}
		return responseBuilder.build();
	}

	@Override
	public Response modules(String token) {
		// TODO Auto-generated method stub
		ResponseBuilder responseBuilder = Response.ok();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			Map<String, String> redisMap = operator.get(token);
			if (redisMap != null && redisMap.isEmpty()) {
				responseBuilder.status(403);// token为空，禁止访问
				log.info("[modules] token为空，禁止访问 " + token);
				return responseBuilder.build();
			}
			log.info("[modules]" + redisMap.toString());
			String expired = redisMap.get("expired");
			Date expiredDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
					.parse(expired);
			long currentDate = System.currentTimeMillis();
			if (currentDate > expiredDate.getTime()) {
				responseBuilder.status(403);// 已过期，禁止访问
				operator.del(token);
				log.info("[modules] token已过期，禁止访问 " + token);
				return responseBuilder.build();
			}

			String appKey = redisMap.get("appKey");
			String identifier = redisMap.get("identifier");
			String platform = redisMap.get("platform");
			String version = redisMap.get("version");
			ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
			ContextThead.setThreadVar(ar.getUsername());// 路由租户数据库
			AppMainVo appVo = appMainApplication
					.getEntitybyIdentify(identifier); // 获取应用信息
			if (appVo == null) {
				responseBuilder.status(400);
				log.info("[modules] identifier不存在 " + identifier);
				return responseBuilder.build();
			}

			AppVersionVo appVersion = appVersionApplication.findByVersion(
					platform, appVo.getId(), version);// 获取对应的版本信息
			if (appVersion != null) {
				List<Map<String, Object>> modules = this.getModules(appVersion);
				result.put("identifier", appVo.getIdentifier());
				result.put("name", appVo.getApp_name());
				result.put("build", appVo.getBuild());
				result.put("modules", modules);
				responseBuilder.entity(result);
				responseBuilder.status(200);
			} else {
				responseBuilder.status(400);
				log.info("[modules] appVersion版本不存在 ");
			}

		} catch (Exception e) {
			log.error("[modules]", e);
			responseBuilder.status(500);
		}
		return responseBuilder.build();
	}

    /**
     * 通过POST请求获取网络数据
	 *
	 * @param toUrl
	 *            访问地址
	 * @param charset
	 *            数据编码格式
	 * @param params
	 * 			     参数
	 * @return 字符串内容
	 */
	private String getStringFromHttpPost(String toUrl, String charset, Map<String,String> params) throws Exception{
		InputStream is = null;
		OutputStream output = null;
		String result = null;
		try {
			// log.info("访问url = =" + toUrl);
			URL url = new URL(toUrl);
			HttpURLConnection http = (HttpURLConnection) url.openConnection();
			http = (HttpURLConnection) url.openConnection();
			http.setDoOutput(true);
			http.setDoInput(true);
			http.setConnectTimeout(8000);
			http.setRequestMethod("POST");
			/*if(UserInfo.getSingleTon().getCookie() != null) {
				http.setRequestProperty("Cookie", UserInfo.getSingleTon().getCookie());
			}*/
			output = http.getOutputStream();
			StringBuilder outStr = new StringBuilder();
			Set<String> keys = params.keySet();
			for (String key : keys) {
				outStr.append("&");
				outStr.append(key);
				outStr.append("=");
				outStr.append(params.get(key));
			}
			output.write(outStr.toString().getBytes(charset == null ? "UTF8": charset));
			output.flush();
			// post返回值
			is = http.getInputStream();

			/*if(toUrl.indexOf(UserInfoConn.URL_LOGIN) != -1){
				UserInfo.getSingleTon().setCookie(http.getHeaderField("Set-Cookie"));
			}*/

			BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset == null ? "UTF8": charset));
			String line = null;
			StringBuffer buffer = new StringBuffer();
			while((line = reader.readLine()) != null) {
			    buffer.append(line);
			}
			//	byte data[] = new byte[1024];
			//	int len = -1;
			//	ByteArrayOutputStream baos = new ByteArrayOutputStream();
			//	while ((len = is.read(data)) != -1) {
			//		baos.write(data, 0, len);
			//	}
			// is.close();
			// result = baos.toString(charset);
			result = buffer.toString();
		} catch (Exception e) {
			throw e;
		} finally {
			if (is != null) {
				is.close();
				is = null;
			}
			if(output != null){
				output.close();
				output = null;
			}
		}
		return result;
	}

	/**
	 * 获取用户模块权限接口（默认是guest）
	 *
	 * @param platform
	 * @param identifier
	 * @param version
	 * @param username
	 * @return
	 */
	@Override
	public Response modulesAuth(String identifier, String username, String appKey) {
		Map<String, String> params = new HashMap<String, String>();
		params.put("identifier", identifier);
		params.put("username", username); // token
		params.put("appKey", appKey);

		// [modulesAuth]{username=token, identifier=com.foreveross.ichangan, appKey=ec691bfe0d4b5b759d154c453ccd02cb}
		log.info("[modulesAuth]" + params.toString());

		ResponseBuilder responseBuilder = Response.ok();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			ApplicationRegisterVO ar = this.appRegServiceClient.getByAppKey(appKey); // 根据租户找到租户内的应用
			if (ar == null) {
				responseBuilder.status(400);// 即appKey密钥不正确
				log.info("[modulesAuth] 即appKey密钥不正确 " + appKey);
				return responseBuilder.build();
			}
			ContextThead.setThreadVar(ar.getUsername());// 路由租户数据库
			AppMainVo appVo = this.appMainApplication.getEntitybyIdentify(identifier); // 获取应用信息
			if (appVo == null) {
				responseBuilder.status(400);// 即identifier不正确
				log.info("[modulesAuth] identifier不正确 " + identifier);
				return responseBuilder.build();
			}
			/** modify by hyw 20140516
			 *
			 * 对接security系统（node适配器），前提在zilla平台先录入好所有role和对应模块权限 modify by hyw 20140516
			 */
			AccountVO acc = this.accountApplication.getEntity(ar.getAccountId());// 根据租户找到注册用户对应的后台账户
			// 根据租户账号得到账号设置相关
			AuthSettingVO authSetting = null;
			// 这里有个问题，因为是作为ws客户端去调用system服务器端，但是system服务器端有个filter过滤权限这样的话就会被拦截
			List<AuthSettingVO> authSettingList = this.authSettingApplication.getEntityByUserName(acc.getUsername()); //changan
			if (!authSettingList.isEmpty()) {
				for (AuthSettingVO authSettingVO : authSettingList) {
					log.info("AuthMethod：" + acc.getAuthType() + ", clientType: " + authSettingVO.getClientType());

					// 注意这里可能要把c改成新增加的角色认证，authSetting.html里面
					if ("r".equals(authSettingVO.getClientType()) && "e".equals(acc.getAuthType())) {
						authSetting = authSettingVO;
						break;
					}
				}
			}
			/**
			 * 检查是否开启zilla-security适配层（获取角色）
			 */
			List<RoleVO> roles = null;
			if (authSetting == null) {
				roles = this.privilegeApplication.rolesPriviliges(username, appVo.getId());
				log.info("native roles");
				/*throw new ApplicationException(AppExcType.getBusCode(AppExcType.APP_LAYER,
						AppExcType.SYS_MODUL, "031"), "auth setting not set ");*/
			} else { // zilla-security获取权限
				log.info("3rd roles");
				Map<String,String> paramMap = new HashMap<String, String>();// 构造POST请求体
				// username是H5回调给原生的，原生请求此方法，所以username那里要保存accessToken而不是username
				paramMap.put("accessToken", "".equals(username) ? "aaa" : username);
				paramMap.put("appId", "ec691bfe0d4b5b759d154c453ccd02cb");
				paramMap.put("secret", "a07fc12f-2ca2-48bc-8276-f64fc13317bf");
				// zilla后台配置,得到3rd信息，开始转发...
				String url = authSetting.getProtocol() + "://" + authSetting.getIp() + ":" + authSetting.getPort() + "/" + authSetting.getUri();

				log.info("开始去adapter获取角色：" + url);
				String rolesjson = this.getStringFromHttpPost(url, null, paramMap); // post token
				log.info("获取完毕：" + rolesjson); // ["normalUser", "leader", "Admin"]
				JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();
				List<String> rolesName = jsonMapper.fromJson(rolesjson, List.class);
				// 获取登陆用户的所授权的模块[roles-modules]
				roles = new ArrayList<RoleVO>();
				RoleVO roleTem = null;
				for (String roleName : rolesName) {
					roleTem = this.roleApplication.getRoleByRoleName(roleName);
					if(roleTem == null)
						continue;
					roles.add(roleTem);
				}
			}
			log.info("roles size: " + roles.size());
			Set<String> set = null;
			if (roles.size() > 0) {
				set = new HashSet<String>();
				StringBuffer rolesTag = new StringBuffer();
				List<PrivilegeVO> listPrivilege = null;
				for (RoleVO role : roles) {// 遍历角色
					// listPrivilege = role.getPrivileges();
					listPrivilege = this.privilegeApplication.getPrivilegesByRoleID(role.getId());

					log.info(role.getName() + ": " + listPrivilege.size());

					if (listPrivilege != null && listPrivilege.size() > 0) {
						for (PrivilegeVO privilege : listPrivilege) {// 遍历角色授权的模块
							this.getOperations_V2(privilege, role.getName(), set);
						}
						log.info("module set: " + set.size());
					}
					// 拼接角色标签tag
					rolesTag.append(role.getName());
					rolesTag.append(",");
					String tag = rolesTag.toString().substring(0, rolesTag.length() - 1);
					result.put("rolesTag", tag);
				}
				// 封装授权的资源
				WidgetVO widgetVO = null;
				List<List<String>> priviliges = new ArrayList<List<String>>();
				for (String jsonStr : set) {

					log.info("setjson: " + jsonStr);

					JSONObject jsb = new JSONObject(jsonStr);
					String roleName = jsb.getString("roleName");
					String module_id = jsb.getString("moduleID");
					String operation = jsb.getString("operation");
					widgetVO = this.widgetApplication.getEntity(module_id);

					log.info("widget: " + widgetVO.getName());

					if (widgetVO != null) {
						List<String> uriList = new ArrayList<String>();
						uriList.add(operation);
						uriList.add(widgetVO.getIdentify());
						uriList.add(roleName);
						priviliges.add(uriList);
					}
				}
				result.put("priviliges", priviliges);
				responseBuilder.status(200);
				responseBuilder.entity(result);
			} else {
				responseBuilder.status(204);
				log.info("[modulesAuth] 没有授权 " + username);
			}
		} catch (Exception e) {
			log.error("[modulesAuth]", e);
			responseBuilder.status(500);
		}
		return responseBuilder.build();
	}

	@Override
	public Map<String, Object> checkUpdate(String identifyer, String platform,
			String appKey) {
		log.info("[checkUpdate]" + identifyer + " " + platform + " " + appKey);
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
			ContextThead.setThreadVar(ar.getUsername());// 路由租户数据库
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
			AppMainVo appVo = appMainApplication
					.getEntitybyIdentify(identifyer); // 获取应用信息
			List<AppVersionVo> listAppVersion = appVersionApplication
					.getAppStatus(appVo.getId(), 4);// 获取应用上架的版本
			if (listAppVersion != null) {
				for (AppVersionVo appversion : listAppVersion) {
					if (appversion.getPlatformid().equals(platform)) {
						result.put("identifier", appVo.getIdentifier());
						result.put("build", appversion.getBuild());
						result.put("version", appversion.getVersion());
						result.put("bundle", appversion.getBundle());
						result.put("plist", appversion.getPlist());
						result.put("releaseNote", appversion.getRelease_note());
						result.put("modifiedAt",
								sf.format(appversion.getModified_time()));
						result.put("result", "success");
						break;
					}
				}
			} else {
				result.put("result", "success");
				result.put("message", "没有上架版本");
			}
		} catch (Exception e) {
			log.error("[checkUpdate]", e);
			result.clear();
			result.put("result", "error");
			result.put("message", "检测应用更新失败！");
		}
		log.info("[checkUpdate]" + result.toString());
		return result;// TODO Auto-generated method stub
	}

	@Override
	public void downFlies(String id, String appKey) throws IOException {
		// 文件存储在默认数据库里面
		HttpServletResponse response = context.getHttpServletResponse();

		AttachmentVO entity = attachmentApplication.getEntity(id);
		if (entity != null && entity.getId() != null) {
			// 读取云服务文件
			FileStorageFactory f = FileStorageFactory.getInstance();
			FileStorage fs = f.getFileStorage();
			FileInfo fileInfo = fs.statFile(entity.getLocalFilename(), null);

			response.setHeader(
					"Content-Disposition",
					String.format("attachment;   filename=%s",
							entity.getUploadFilename()));
			response.setHeader("Content-Type", entity.getContentType());
			response.setHeader("Content-Length", fileInfo.getLength() + "");
			OutputStream out = response.getOutputStream();
			fs.fetchFile(entity.getLocalFilename(), null, out);
			out.flush();
			out.close();
		} else {
			response.setStatus(500);
		}
	}

	@Override
	public List<Map<String, String>> widgetSnapshot(String identifier,
			String version, String appKey) {
		log.info("[widgetSnapshot]" + identifier + " " + version + " " + appKey);
		// TODO Auto-generated method stub
		ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
		ContextThead.setThreadVar(ar.getUsername());// 路由租户数据库
		WidgetVersionVO versionVo = widgetVersionApplication.checkIdentity(
				identifier, version);
		List<Map<String, String>> result = new ArrayList<Map<String, String>>();
		if (versionVo != null) {
			List<WidgetSnapshotVO> list = widgetSnapshotApplication
					.findByVersionId(versionVo.getId());
			if (list != null) {
				for (WidgetSnapshotVO shot : list) {
					Map<String, String> map = new HashMap<String, String>();
					map.put("snapshot", shot.getSnapshot());
					result.add(map);
				}
			}
		}
		log.info("[widgetSnapshot]" + result.toString());
		return result;
	}

	// 添加下载监控日志 add by lizhifeng
	public void addDownLogs(String appKey, String version, String platform) {
		log.info("the method name is [addDownLogs]");
		ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
		ContextThead.setThreadVar(ar.getUsername());
		String appId = ar.getAppId();
		AppMainVo appMainVo = appMainApplication.getEntity(appId);
		/*
		 * 效能监控，暂时注释掉 try { MonitorVO monitorVO = new MonitorVO();
		 * monitorVO.setAction("appDownload"); monitorVO .setClassName(
		 * "com.foreveross.bsl.mam.app.application.impl.ClientWsApplicationImpl"
		 * ); monitorVO.setMethodName("updateAppDownCount");
		 * monitorVO.setAppName(appMainVo.getIdentifier());
		 * monitorVO.setVersion(version); monitorVO.setPlatformId(platform);
		 * monitorApplication.SaveAppDownLog(monitorVO.getAction(),
		 * monitorVO.getClassName(), monitorVO.getMethodName(),
		 * monitorVO.getUserName(), monitorVO.getAppName(),
		 * monitorVO.getModuleName(), ar.getUsername(), version, platform); }
		 * catch (Exception e) { e.printStackTrace();
		 * log.error("下载监控插入日志失败，请检查是否开启监控服务"); }
		 */

	}

	@Override
	public Map<String, Object> updateAppDownCount(String version,
			String appKey, String platform) {
		log.info("the method name is [updateAppDownCount]");
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
			ContextThead.setThreadVar(ar.getUsername());
			List<AppVersionVo> appversions = appVersionApplication
					.findByPlatform(platform, ar.getAppId());
			AppVersionVo appVersion = null;
			if (appversions != null && !appversions.isEmpty()) {
				for (AppVersionVo vo : appversions) {
					if (platform.equalsIgnoreCase(vo.getPlatformid())) {
						appVersion = vo;
						break;
					}
				}
			}
			log.info("[ClientWsApplicationImpl]-updateAppDownCount pre version counter->"
					+ appVersion.getVersion_counter());
			appVersion.setVersion_counter(appVersion.getVersion_counter() + 1);
			appVersionApplication.updateEntity(appVersion.getId(), appVersion);
			AppMainVo app = appMainApplication.getEntity(appVersion
					.getApplicationid());
			app.setDownload_counter(app.getDownload_counter() + 1);
			log.info("[ClientWsApplicationImpl]-updateAppDownCount new version counter->"
					+ appVersion.getVersion_counter());

			appMainApplication.updateEntity(app.getId(), app);
			try {
				// add by lizhifeng 添加下载监控,需要开启监控服务
				addDownLogs(appKey, version, appVersion.getPlatformid());
			} catch (Exception e) {
				log.error("下载监控日志插入失败，请检查是否开启监控服务：" + e);
			}
			result.put("result", "success");
		} catch (Exception e) {
			result.put("result", "faile");
			result.put("msg", "更新发生异常");
			e.printStackTrace();
		}

		return result;
	}

	/**
	 * 提供第三方系统下载架上应用包
	 *
	 * @param appKey
	 *            应用key
	 *
	 * @param platform
	 *            应用platform
	 * @return
	 */
	public AppVersionVo downAppPlat(String identifier, String appKey,
			String platform, String version) {

		ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
		ContextThead.setThreadVar(ar.getUsername());
		AppMainVo appVo = appMainApplication.getEntitybyIdentify(identifier);
		AppVersionVo appVersion = null;
		if (appVo != null) {
			if (StringUtils.isNotEmpty(version)) {// 版本号不为空，则查询当前版本
				appVersion = appVersionApplication.findByVersion(platform,
						appVo.getId(), version);
				if (appVersion != null) {
					appVersion.setVersion_counter(appVersion
							.getVersion_counter() + 1);
					appVersion
							.setPlat_counter(appVersion.getPlat_counter() + 1);
					appVersionApplication.saveEntity(appVersion); // 记录版本次数
					appVo.setDownload_counter(appVo.getDownload_counter() + 1);
					appMainApplication.saveEntity(appVo);// 记录应用总次数
				}
			} else {// 否则查询上架版本
				List<AppVersionVo> apps = appVersionApplication.getAppStatus(
						appVo.getId(), 4);
				for (AppVersionVo versionVo : apps) {
					if (platform.equalsIgnoreCase(versionVo.getPlatformid())) {
						versionVo.setVersion_counter(versionVo
								.getVersion_counter() + 1);
						appVersionApplication.saveEntity(versionVo); // 记录版本次数
						appVo.setDownload_counter(appVo.getDownload_counter() + 1);
						appMainApplication.saveEntity(appVo);// 记录应用总次数
						appVersion = versionVo;
						break;
					}
				}
			}
			/*
			 * 效能监控，暂时注释掉 try { MonitorVO monitorVO = new MonitorVO();
			 * monitorVO.setAction("appDownload"); monitorVO .setClassName(
			 * "com.foreveross.bsl.mam.app.application.impl.ClientWsApplicationImpl"
			 * ); monitorVO.setMethodName("downAppPlat()");
			 * monitorVO.setAppName(identifier); monitorVO.setVersion(version);
			 * monitorVO.setPlatformId(platform); ObjectMapper objectMapper =
			 * new ObjectMapper(); String monitorJson =
			 * objectMapper.writeValueAsString(monitorVO);
			 * monitorApplication.saveEntity(monitorJson); } catch (Exception e)
			 * { e.printStackTrace(); log.error("下载监控插入日志失败，请检查是否开启监控服务"); }
			 */
		}
		return appVersion;
	}

	/**
	 * 根据appid判断登陆是否使用第三方接口验证
	 *
	 * @param appId
	 * @return true,false
	 */
	private boolean isAppExtend(String appId, String appKey) {
		if (StringUtils.isEmpty(appKey)) {
			appKey = appRegServiceClient.getAppKeyByAppId(appId);
		}
		log.info("appKey:" + appKey);
		ApplicationRegisterVO ar = appRegServiceClient.getByAppKey(appKey);
		AccountVO acc = new AccountVO();
		boolean flag = false;
		if (ar != null) {
			acc = accountApplication.getEntity(ar.getAccountId());
			if (acc != null) {
				// current User auth type
				String code = acc.getAuthType() != null ? acc.getAuthType()
						: AuthType.Default.getValue();
				AuthType authType = AuthType.getByCode(code);
				switch (authType) {
				case External:
					flag = true;
					break;
				default:
					flag = false;
					break;
				}
			}

		}
		return flag;
	}

	private Map<String, Object> getAppsWidgets(String platform,
			String identifier, String version, String username, String appKey) {
		log.info("[getAppsWidgets]" + platform + " " + identifier + " "
				+ version + " " + username + " appKey:" + appKey);
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			List<Map<String, Object>> modules = new ArrayList<Map<String, Object>>();
			if (StringUtils.isNotEmpty(appKey)) {
				ApplicationRegisterVO ar = appRegServiceClient
						.getByAppKey(appKey);
				ContextThead.setThreadVar(ar.getUsername());// 路由租户数据库
			}
			AppMainVo appVo = appMainApplication
					.getEntitybyIdentify(identifier); // 获取应用信息
			result.put("identifier", appVo.getIdentifier());
			result.put("name", appVo.getApp_name());
			result.put("build", appVo.getBuild());
			AppVersionVo appVersion = appVersionApplication.findByVersion(
					platform, appVo.getId(), version);// 获取对应的版本信息

			boolean isTrue = this.isAppExtend(appVo.getId(), appKey);// 是否是验证第三方系统权限
			// 获取登陆用户的所授权的摸摸
			Map<String, List> mapWidgetRole = null;
			if (!isTrue) {
				mapWidgetRole = privilegeApplication.authorize(username,
						appVo.getId());
			}
			if (appVersion != null) {
				List<AppVersionWidgetVersionVo> listAppWidget = appVersionWidgetVersionApplication
						.getListByPlatEntity(platform, version, appVo.getId());// 根据版本id获取应用关联模块信息

				List<WidgetVersionVO> listWidgetVersionVo = new ArrayList<WidgetVersionVO>();
				for (AppVersionWidgetVersionVo appWidget : listAppWidget) {
					WidgetVersionVO widgetVersionVo = widgetVersionApplication
							.widgetVersion(appWidget.getWidgetId(),
									appWidget.getWidgetVersion());
					if (widgetVersionVo != null) {
						widgetVersionVo = widgetVersionApplication
								.getEntity(widgetVersionVo.getId());
						listWidgetVersionVo.add(widgetVersionVo);
					}
				}
				// 封装返回给客户端的参数
				for (WidgetVersionVO widgetVersionVo : listWidgetVersionVo) {
					Map<String, Object> mapModules = new HashMap<String, Object>();
					if (widgetVersionVo.getWidgetVo() != null) {
						mapModules.put("identifier", widgetVersionVo
								.getWidgetVo().getIdentify());
						mapModules.put("name", widgetVersionVo.getWidgetVo()
								.getName());
						mapModules.put("isAutoShow", widgetVersionVo
								.getWidgetVo().isAutoShow());
						mapModules.put("showIntervalTime", widgetVersionVo
								.getWidgetVo().getShowIntervalTime());
						mapModules.put("timeUnit", widgetVersionVo
								.getWidgetVo().getTimeUnit());
						mapModules.put("build", widgetVersionVo.getBuild());

						mapModules.put("version", widgetVersionVo.getVersion());
						mapModules.put("releaseNote",
								widgetVersionVo.getRelease_not());
						mapModules.put("category", widgetVersionVo
								.getWidgetVo().getCategoryVO().getName());
						mapModules.put("bundle", widgetVersionVo.getBoundle());
						mapModules.put("hidden", widgetVersionVo.getWidgetVo()
								.isHidden());
						mapModules.put("sortingWeight", widgetVersionVo
								.getWidgetVo().getSortingWeight());
						mapModules.put("isAutoShow", widgetVersionVo
								.getWidgetVo().isAutoShow());
						mapModules.put("showIntervalTime", widgetVersionVo
								.getWidgetVo().getShowIntervalTime());
						mapModules.put("timeUnit", widgetVersionVo
								.getWidgetVo().getTimeUnit());
						mapModules.put("autoDownload", widgetVersionVo
								.getWidgetVo().isAutoDownload());

						// 本地模块 不需要在服务器获取icon 把本地模块icon名称加到icon里
						if (!StringUtils.isEmpty(widgetVersionVo.getWidgetVo()
								.getLocal())) {
							mapModules.put("local", widgetVersionVo
									.getWidgetVo().getLocal());
							mapModules.put("icon", "local:"
									+ widgetVersionVo.getWidgetVo().getLocal()
									+ ".png");
						} else {
							mapModules.put("icon", widgetVersionVo
									.getWidgetVo().getIcon_id());
						}
						String widgetid = widgetVersionVo.getWidget_id();
						if (mapWidgetRole != null
								&& mapWidgetRole.get(widgetid) != null) {// 赋值权限
							mapModules.put("privileges",
									mapWidgetRole.get(widgetid));
						} else {
							if (isTrue) {
								mapModules.put("privileges", new ArrayList());// 第三方权限验证，默认对关联的所有模块都有访问权限
							}
						}
						modules.add(mapModules);
					}
				}
			}
			result.put("modules", modules);
			result.put("result", "success");
		} catch (Exception e) {
			log.error("[getApps]", e);
			result.clear();
			result.put("result", "error");
			result.put("message", "获取应用信息失败！");
		}
		log.info("[getApps]" + result.toString());
		return result;
	}

	/**
	 * 获取应用版本所关联的模块信息
	 *
	 * @param appVersion
	 * @return
	 */
	private List<Map<String, Object>> getModules(AppVersionVo appVersion) {

		List<Map<String, Object>> modules = new ArrayList<Map<String, Object>>();
		List<AppVersionWidgetVersionVo> listAppWidget = appVersionWidgetVersionApplication
				.getListByPlatEntity(appVersion.getPlatformid(),
						appVersion.getVersion(), appVersion.getApplicationid());// 根据版本id获取应用关联模块信息
		List<WidgetVersionVO> listWidgetVersionVo = new ArrayList<WidgetVersionVO>();
		for (AppVersionWidgetVersionVo appWidget : listAppWidget) {
			WidgetVersionVO widgetVersionVo = widgetVersionApplication
					.widgetVersion(appWidget.getWidgetId(),
							appWidget.getWidgetVersion());
			if (widgetVersionVo != null) {
				widgetVersionVo = widgetVersionApplication
						.getEntity(widgetVersionVo.getId());
				listWidgetVersionVo.add(widgetVersionVo);
			}
		}
		// 封装返回给客户端的参数
		for (WidgetVersionVO widgetVersionVo : listWidgetVersionVo) {
			Map<String, Object> mapModules = new HashMap<String, Object>();
			if (widgetVersionVo.getWidgetVo() != null) {
				mapModules.put("identifier", widgetVersionVo.getWidgetVo()
						.getIdentify());
				mapModules.put("name", widgetVersionVo.getWidgetVo().getName());
				mapModules.put("isAutoShow", widgetVersionVo.getWidgetVo()
						.isAutoShow());
				mapModules.put("showIntervalTime", widgetVersionVo
						.getWidgetVo().getShowIntervalTime());
				mapModules.put("timeUnit", widgetVersionVo.getWidgetVo()
						.getTimeUnit());
				mapModules.put("build", widgetVersionVo.getBuild());

				mapModules.put("version", widgetVersionVo.getVersion());
				mapModules.put("releaseNote", widgetVersionVo.getRelease_not());
				mapModules.put("category", widgetVersionVo.getWidgetVo()
						.getCategoryVO().getName());
				mapModules.put("bundle", widgetVersionVo.getBoundle());
				mapModules.put("hidden", widgetVersionVo.getWidgetVo()
						.isHidden());
				mapModules.put("sortingWeight", widgetVersionVo.getWidgetVo()
						.getSortingWeight());
				mapModules.put("isAutoShow", widgetVersionVo.getWidgetVo()
						.isAutoShow());
				mapModules.put("showIntervalTime", widgetVersionVo
						.getWidgetVo().getShowIntervalTime());
				mapModules.put("timeUnit", widgetVersionVo.getWidgetVo()
						.getTimeUnit());
				mapModules.put("autoDownload", widgetVersionVo.getWidgetVo()
						.isAutoDownload());

				// 本地模块 不需要在服务器获取icon 把本地模块icon名称加到icon里
				if (!StringUtils.isEmpty(widgetVersionVo.getWidgetVo()
						.getLocal())) {
					mapModules.put("local", widgetVersionVo.getWidgetVo()
							.getLocal());
					mapModules
							.put("icon", "local:"
									+ widgetVersionVo.getWidgetVo().getLocal()
									+ ".png");
				} else {
					mapModules.put("icon", widgetVersionVo.getWidgetVo()
							.getIcon_id());
				}
				// if (widgetVersionVo.getWidgetVo().isAppAuth()) {
				// mapModules.put("privileges", new ArrayList());// 默认访问权限
				// }
				modules.add(mapModules);
			}
		}
		return modules;
	}

	/**
	 * 封装每一个操作资源
	 *
	 * @param privilege
	 * @param roleName
	 * @return
	 */
	private void getOperations(PrivilegeVO privilege, String roleName,
			Set<String> set) {
		if (privilege.getOperations() != null) {
			JSONObject json = null;
			try {
				for (OperationVO vo : privilege.getOperations()) {
					json = new JSONObject();
					json.put("moduleID", privilege.getModule_ID());
					json.put("roleName", roleName);
					json.put("operation", vo.getCode());
					set.add(json.toString());
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 封装每一个操作资源
	 *
	 * @param privilege
	 * @param roleName
	 * @return
	 */
	private void getOperations_V2(PrivilegeVO privilege, String roleName,
			Set<String> set) {
		if (privilege.getOperation_IDs() != null) {
			List<OperationVO> operVoList=operationApplication.getOperations(privilege.getOperation_IDs());
			if(null==operVoList || operVoList.isEmpty())
				return;
			JSONObject json = null;
			try {
				for (OperationVO vo : operVoList) {
					json = new JSONObject();
					json.put("moduleID", privilege.getModule_ID());
					json.put("roleName", roleName);
					json.put("operation", vo.getCode());
					set.add(json.toString());
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

}